package com.example.blogsystem.controller;

import com.example.blogsystem.common.ResultAjax;
import com.example.blogsystem.common.SessionUtils;
import com.example.blogsystem.model.Articleinfo;
import com.example.blogsystem.model.Userinfo;
import com.example.blogsystem.model.vo.UserinfoVO;
import com.example.blogsystem.service.ArticleService;
import com.example.blogsystem.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created with IntelliJ IDEA.
 * Description: 文章控制器
 * User: DELL
 * Date: 2023-09-03
 * Time: 23:03
 */
@RestController
@RequestMapping("/art")
public class ArticleController {
    public static final int _DESC_LENGTH = 120;  // 文章简介的长度
    public static final int _DEFAULT_PAGE_SIZE = 3; // 文章列表页中默认的

    @Autowired
    private ArticleService articleService;
    @Autowired
    @Qualifier("myThreadPool")
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private UserService userService;

    /**
     * 查询当前登录用户的所有文章
     *
     * @param request
     * @return
     */
    @RequestMapping("/mylist")
    public ResultAjax myList(HttpServletRequest request) {
        // 1.得到当前登录用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-1, "登录状态异常,请先登录! ");
        }
        // 2.根据用户 id 来查询此用户发表的所有文章
        List<Articleinfo> articles = articleService.getArticleByUid(userinfo.getId());
        // 将文章正文处理成文章简介
        if (articles != null && articles.size() > 0) {
            // 并行处理文章列表
            articles.stream().parallel().forEach((articleinfo -> {
                if (articleinfo.getContent().length() > _DESC_LENGTH) {
                    articleinfo.setContent(articleinfo.getContent().substring(0, _DESC_LENGTH));
                }
            }));
        }
        // 3.将查询结果返回给前端
        return ResultAjax.success(articles);
    }

    /**
     * 删除文章
     *
     * @return
     */
    @RequestMapping("/del")
    public ResultAjax del(Integer aid, HttpServletRequest request) {
        // 1.参数校验
        if (aid == null || aid <= 0) {
            return ResultAjax.fail(-1, "参数异常!");
        }
        // 2.得到当前登录用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null || userinfo.getId() <= 0) {
            return ResultAjax.fail(-2, "请先登录!");
        }
        // 3.判断文章的归属人 + 删除操作
        int result = articleService.delByAidAndUid(aid, userinfo.getId());
        // 4.返回结果
        return ResultAjax.success(result);
    }

    /**
     * 发布博客
     *
     * @param articleinfo
     * @param request
     * @return
     */
    @RequestMapping("/add")
    public ResultAjax add(Articleinfo articleinfo, HttpServletRequest request) {
        // 1.校验参数 (不为空 + title 不能以空格开头)
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle())
                || !StringUtils.hasLength(articleinfo.getContent())
                || articleinfo.getTitle().charAt(0) == ' ') {
            return ResultAjax.fail(-1, "博客内容不合法!");
        }
        // 2.得到当前登陆用户信息
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2, "请先登录!");
        }
        articleinfo.setUid(userinfo.getId());
        // 3.添加博客
        int result = articleService.add(articleinfo);
        // 4.将得到的结果返回给用户
        return ResultAjax.success(result);
    }

    /**
     * 修改博客页面的初始化中得到特定 id 的博客
     *
     * @param id
     * @return
     */
    @RequestMapping("/update_init")
    public ResultAjax updateInit(Integer id, HttpServletRequest request) {
        // 1.参数校验
        if (id == null || id <= 0) {
            return ResultAjax.fail(-1, "参数异常!");
        }
        // 2.得到当前登录用户
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2, "请先登录!");
        }
        // 3.查询博客 + 用户校验
        Articleinfo articleinfo = articleService.getByAidAndUid(id, userinfo.getId());
        // 4.将结果返回给前端
        return ResultAjax.success(articleinfo);
    }

    /**
     * 修改博客
     *
     * @param articleinfo
     * @param request
     * @return
     */
    @RequestMapping("/update")
    public ResultAjax update(Articleinfo articleinfo, HttpServletRequest request) {
        // 1.校验参数 (不为空 + title 不能以空格开头)
        if (articleinfo == null || !StringUtils.hasLength(articleinfo.getTitle())
                || !StringUtils.hasLength(articleinfo.getContent())
                || articleinfo.getTitle().charAt(0) == ' '
                || articleinfo.getId() <= 0) {
            return ResultAjax.fail(-1, "博客内容不合法!");
        }
        // 2.得到当前登陆用户信息
        Userinfo userinfo = SessionUtils.getUser(request);
        if (userinfo == null) {
            return ResultAjax.fail(-2, "请先登录!");
        }
        articleinfo.setUid(userinfo.getId());
        // 3.判断文章归属人 + 更新博客
        int result = articleService.update(articleinfo);
        // 将结果返回给前端
        return ResultAjax.success(result);
    }

    /**
     * 文章详情页
     *
     * @param id 文章id
     * @return 用户信息 + 文章详情
     */
    @RequestMapping("detail")
    public ResultAjax getDetail(Integer id) throws ExecutionException, InterruptedException {
        // 1.参数校验
        if (id == null || id <= 0) {
            return ResultAjax.fail(-1, "非法参数!");
        }
        // 2.根据文章 id 查询文章详情信息
        Articleinfo articleinfo = articleService.getByAid(id);
        if (articleinfo == null || articleinfo.getId() <= 0) {
            return ResultAjax.fail(-1, "非法参数!");
        }
        // 3.根据 uid 查询用户信息
        FutureTask<UserinfoVO> userTask = new FutureTask<>(() -> {
            return userService.getUserById(articleinfo.getUid());
        });
        taskExecutor.submit(userTask);
        // 4.根据 uid 查询用户发表的总文章数
        FutureTask<Integer> countTask = new FutureTask<>(() -> {
            return articleService.getCountByUid(articleinfo.getUid());
        });
        taskExecutor.submit(countTask);
        // 5.组装数据
        UserinfoVO userinfoVO = userTask.get();
        Integer artCount = countTask.get();
        userinfoVO.setArtCount(artCount);
        HashMap<String, Object> result = new HashMap<>();
        result.put("user", userinfoVO);
        result.put("art", articleinfo);
        // 6.将结果返回给前端
        return ResultAjax.success(result);
    }

    /**
     * 访问文章详情页时,阅读量增加
     *
     * @param id
     * @return
     */
    @RequestMapping("/rcount_increment")
    public ResultAjax readCountIncrement(Integer id) {
        // 1.参数校验
        if (id == null || id <= 0) {
            return ResultAjax.fail(-1, "非法参数");
        }
        // 2.将对应 id 的文章的阅读量加 1
        int result = articleService.readCountIncrement(id);
        // 3.返回结果给前端
        return ResultAjax.success(result);
    }

    /**
     * 根据 页码 + 每页博客数 返回特定博客
     *
     * @param pindex
     * @param psize
     * @return
     */
    @RequestMapping("/getlistbypage")
    public ResultAjax getListOfPage(Integer pindex, Integer psize) throws ExecutionException, InterruptedException {
        // 1.加工参数
        if (pindex == null || pindex <= 0) {
            pindex = 1;
        }
        if (psize == null || psize <= 0) {
            psize = _DEFAULT_PAGE_SIZE;
        }
        // 2.并发进行文章列表和总页数的查询
        int size = psize;
        int index = pindex;
        FutureTask<List<Articleinfo>> getListTask = new FutureTask<>(() -> {
            int offset = size * (index - 1);
            return articleService.getArtByPage(size, offset);
        });
        taskExecutor.submit(getListTask);
        FutureTask<Integer> getCountTask = new FutureTask<>(() -> {
            // 得到总文章数,并计算出总页数
            int totalCount = articleService.getAllArtCount();
            double countTemp = totalCount * 1.0 / size;
            return (int) Math.ceil(countTemp);
        });
        taskExecutor.submit(getCountTask);
        // 3.组装数据
        List<Articleinfo> articles = getListTask.get();
        // 将文章正文处理成文章简介
        if (articles != null && articles.size() > 0) {
            // 并行处理文章列表
            articles.stream().parallel().forEach((articleinfo -> {
                if (articleinfo.getContent().length() > _DESC_LENGTH - 10) {
                    articleinfo.setContent(articleinfo.getContent().substring(0, _DESC_LENGTH - 10));
                }
            }));
        }
        int pcount = getCountTask.get();
        HashMap<String, Object> result = new HashMap<>();
        result.put("list", articles);
        result.put("count", pcount);
        // 4.将结果返回给前端
        return ResultAjax.success(result);
    }

}
